#if 1
#include "TCPServerContainer.h"
#include "UDPGroupContainer.h"
#include "KCPServerContainer.h"
#include <QtWidgets/QApplication>
int main(int argc, char* argv[])
{
	QApplication a(argc, argv);
	KCPServerContainer w;
	w.show();
	return a.exec();
}
#else
#include "Transmission/TCP/TCPServer.h"
#include "Transmission/UDP/UDPClient.h"
#include "Transmission/UDP/UDPGroup.h"
#include <windows.h>
#include <iostream>
extern uint32_t CreateRef;
extern uint32_t DestroyRef;
static int64_t gettime_internal_test()
{
#if _WIN32
	FILETIME ft;
	int64_t t;
	GetSystemTimeAsFileTime(&ft);
	t = (int64_t)ft.dwHighDateTime << 32 | ft.dwLowDateTime;
	return t / 10 - 11644473600000000;
#else
	struct timeval tv;
	gettimeofday(&tv, NULL);
	return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
#endif
}
uint32_t GetTimestampTest()
{
	return (uint32_t)((gettime_internal_test() / 1000) & 0xfffffffful);
}
uint32_t lastts;
uint32_t fps;
bool isExit = false;
void CalcData(bool force = false)
{
	fps++;
	if (GetTimestampTest() - lastts > 1000 || force)
	{
		std::cout <<  CreateRef << "\t\t" << DestroyRef << "\t\t fps : " << fps << std::endl;
		fps = 0;
		lastts = GetTimestampTest();
	}
}

void recv_udp_cmd(char* buffer, int len, sockaddr_in* remote)
{
	if (len == 4 && !strncmp(buffer, "exit", 4))
		isExit = true;
}

void cmd_udp()
{
	
	UDPClient* udp = nullptr;
	udp = new UDPClient();
	if (!udp->Initialize(10000))
	{
		printf("cmd udp bind error\n");
		exit(-1);
	}
	udp->RegisterReceivedCallback(recv_udp_cmd);
	while (!isExit)
	{
		udp->Update();
		Sleep(100);
	}
	udp->Terminate();
	delete udp;
}



void OnTCPServerClientConnected(TCPClient* client)
{
	client->Disconnect();
	client->Send((char*)"TEST.", 5);
}

void OnTCPServerDisconnected(TCPClient* client)
{
	
}

void OnTCPServerClientReceived(TCPClient* client, char* data, int len)
{
	
}

void test_tcpserver()
{
	TCPServer server;
	server.RegisterClientConnectedCallback(OnTCPServerClientConnected);
	server.RegisterClientDisconnectedCallback(OnTCPServerDisconnected);
	server.RegisterClientReceivedCallback(OnTCPServerClientReceived);
	server.Initialize(5555);
	lastts = GetTimestampTest();
	fps = 0;
	while (!isExit)
	{
		server.Update();
		CalcData();
		Sleep(1);
	}
	server.Terminate();
}

TCPClient* tcpclient = nullptr;
void OnConnectResult(int ret)
{
	tcpclient->AsyncConnect("120.76.245.49", 5555);
}

void OnDisconnected()
{

}

void OnReceived(char* data, int len)
{

}

void test_tcpclient()
{
	tcpclient = new TCPClient();
	tcpclient->AsyncConnect("120.76.245.49", 5555);
	tcpclient->RegisterConnectCompletedCallback(OnConnectResult);
	tcpclient->RegisterReceivedCallback(OnReceived);
	tcpclient->RegisterDisconnectedCallback(OnDisconnected);
	while (!isExit)
	{
		tcpclient->Update();
		CalcData();
		Sleep(1);
	}
	tcpclient->Disconnect();
	delete tcpclient;
}

UDPClient* udpclient;
void UDPClientReceived(char* data, int size, sockaddr_in* addr)
{
	
}

void test_udpclient()
{
	udpclient = new UDPClient();
	udpclient->RegisterReceivedCallback(UDPClientReceived);
	udpclient->Initialize(5555);
	char buf[1024];
	while (!isExit)
	{
		for (int i = 0; i < 10; i++)
			udpclient->SendTo(buf, 1024, "192.168.2.33", 564);
		udpclient->Update();
		CalcData();
		Sleep(1);
	}
	udpclient->Terminate();
	delete udpclient;
}
UDPClient* udp1 = nullptr;
UDPClient* udp2 = nullptr;
void UDPGroupRecv(char* buffer, int len, sockaddr_in* remote, UDPClient* client)
{
	if (!udp1)
		throw;
	client->SendTo(buffer, len, remote);
}
void test_udpgroup()
{
	UDPGroup group;
	group.Initialize();
	int ts = GetTimestampTest();

	group.RegisterReceivedCallback(UDPGroupRecv);
	while (!isExit)
	{
		if (GetTimestampTest() - ts > 500)
		{
			ts = GetTimestampTest();
			if (udp1)
			{
				group.RemoveClient(udp1);
				group.RemoveClient(udp2);
				delete udp1;
				delete udp2;
				udp1 = udp2 = nullptr;
			}
			else
			{
				udp1 = new UDPClient();
				udp2 = new UDPClient();
				group.AddClient(udp1, 5555);
				group.AddClient(udp2, 5556);
			}
		}
		CalcData();
		group.Update();
		Sleep(1);
	}
	group.Terminate();

}
int main(int argc, char* argv[])
{
	std::thread testthread(cmd_udp);
	//test_tcpserver();
	//test_tcpclient();
	//test_udpclient();
	test_udpgroup();
	testthread.join();
	CalcData(true);
	return 0;
}
#endif
